package com.um.jdy.baofu.api.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.um.jdy.baofu.api.BaofuPayService;
import com.um.jdy.baofu.config.BaofuPayConfig;
import com.um.jdy.baofu.entity.pay.PostMasterEntity;
import com.um.jdy.baofu.entity.pay.ResultMasterEntity;
import com.um.jdy.baofu.entity.pay.RiskInfoEntity;
import com.um.jdy.baofu.http.HttpUtil;
import com.um.jdy.baofu.rsa.JHSignatureUtils;
import com.um.springboot.starter.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class BaofuPayServiceImpl implements BaofuPayService {
    @Autowired
    BaofuPayConfig baofuPayConfig;
    @Override
    public Map<String, Object> createOrderByJsapi(String outTradeNo, Integer amount, String description, String openId, String appid, String subMchId,String type,String comId) {
        //小程序只有微信支付
        String method ="unified_order";
        String payCode = "WECHAT_JSAPI"; //"ALIPAY_NATIVE";//"WECHAT_JSAPI";//QUICK_PASS_NATIVE//QUICK_PASS_APP
        Map<String,Object> Biz_Content = new HashMap<String,Object>();
        Biz_Content.put("agentMerId", "");
        Biz_Content.put("agentTerId", "");
        Biz_Content.put("merId", baofuPayConfig.getMemberid());
        Biz_Content.put("terId", baofuPayConfig.getTerminalid());
        Biz_Content.put("outTradeNo", outTradeNo);
        Biz_Content.put("txnAmt", amount);
        Biz_Content.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        Biz_Content.put("totalAmt", amount);
        Biz_Content.put("timeExpire", baofuPayConfig.getTimeExpire());//订单支付的有效时间，单位：分钟
        Biz_Content.put("prodType", baofuPayConfig.getProdType());//SHARING:分账产品,ORDINARY:普通产品
        Biz_Content.put("payCode", payCode);
        //小程序必穿参数
        Map<String,Object> Pay_Extend = new HashMap<String,Object>();
        Pay_Extend.put("body", description);
        Pay_Extend.put("sub_appid", appid);
        Pay_Extend.put("sub_openid", openId);

        Biz_Content.put("payExtend", Pay_Extend);

        String notifyUrl = StrUtil.builder(
                baofuPayConfig.getNotifyUrl(), type,"/",comId).toString();
        System.out.println(notifyUrl);
        //Biz_Content.put("feeMerId", "");
        //微信商户id
        Biz_Content.put("subMchId", subMchId);
        Biz_Content.put("notifyUrl",notifyUrl);
        Biz_Content.put("pageUrl", baofuPayConfig.getPayPageUrl());
        Biz_Content.put("forbidCredit", baofuPayConfig.getForbidCredit());//1：禁止,0：不禁止;不传默认为0
        //预留i段
        // Biz_Content.put("attach", "");
        //请求方保留域
        Biz_Content.put("reqReserved", "123456");

        ///风控参数
        RiskInfoEntity rie = new RiskInfoEntity();
        rie.setLocationPoint("");
        rie.setClientIp(getIpAddress());
        Biz_Content.put("riskInfo", rie);
        try{
            PostMasterEntity pme = new PostMasterEntity();

            String BizContent= JSON.toJSONString(Biz_Content);
            log.info(BizContent);

            String BizContentEn = JHSignatureUtils.encryptByRSA(BizContent, baofuPayConfig.getPripath(), baofuPayConfig.getPfxpwd());

            pme.setBizContent(BizContent);
            pme.setSignStr(BizContentEn);
            pme.setMerId(baofuPayConfig.getMemberid());
            pme.setTerId(baofuPayConfig.getTerminalid());
            pme.setMethod(method);

            log.info("请求参数"+pme);

            String PostString  = HttpUtil.RequestForm(baofuPayConfig.getPayUrl(),pme);

            log.info("返回参数："+PostString);
            ResultMasterEntity rme =  JSON.parseObject(PostString,ResultMasterEntity.class);

            log.info(rme.toString());
            if(rme.getReturnCode().equals("SUCCESS")){
                if(JHSignatureUtils.verifySignature(baofuPayConfig.getCerpath(), rme.getDataContent(), rme.getSignStr())){
                    log.info("YES");
                    JSONObject json =JSON.parseObject(rme.getDataContent());
                    if(json.getString("resultCode").equals("SUCCESS")){
                        JSONObject json1 =JSON.parseObject(json.getString("chlRetParam"));
                        Map<String,Object> map = JSON.parseObject(json1.getString("wc_pay_data"),Map.class);
                        return toUnderlineCase(map);
                    }else {
                        throw new ServiceException(json.getString("errMsg"));
                    }
                }else {
                    log.info("NO");
                    throw new ServiceException("支付验证数据失败");
                }
            }else {
                throw new ServiceException(rme.getReturnMsg());
            }
        }catch (Exception e){
            throw new ServiceException("支付失败："+e.getMessage());
        }
    }

    @Override
    public Map<String, Object> refundOrder(String outTradeNo, String outRefundNo, Integer payAmount, Integer refundAmount,String type,String comId) {
        String notifyUrl = StrUtil.builder(
                baofuPayConfig.getNotifyUrl(), type,"/",comId).toString();
        System.out.println(notifyUrl);
        String txnTime=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//报文发送日期时间
        String method = "order_refund";
        Map<String,Object> Biz_Content = new HashMap<String,Object>();
        Biz_Content.put("agentMerId", "");
        Biz_Content.put("agentTerId", "");
        Biz_Content.put("merId", baofuPayConfig.getMemberid());
        Biz_Content.put("terId", baofuPayConfig.getTerminalid());
        //Biz_Content.put("originTradeNo", outTradeNo);
        Biz_Content.put("originOutTradeNo", outTradeNo);
        Biz_Content.put("outTradeNo", outRefundNo);
        Biz_Content.put("notifyUrl", notifyUrl);
        //Biz_Content.put("merchantName", merchantName);
        Biz_Content.put("refundAmt", refundAmount);
        Biz_Content.put("totalAmt", refundAmount);
        Biz_Content.put("txnTime", txnTime);
        Biz_Content.put("attach", "");//预留字段
        Biz_Content.put("reqReserved", "");//请求方保留域
        Biz_Content.put("refundReason", "退款");
        try{
            PostMasterEntity pme = new PostMasterEntity();
            String BizContent= JSON.toJSONString(Biz_Content);;
            log.info("请求报文："+BizContent);

            String BizContentEn = JHSignatureUtils.encryptByRSA(BizContent, baofuPayConfig.getPripath(), baofuPayConfig.getPfxpwd());

            pme.setBizContent(BizContent);
            pme.setSignStr(BizContentEn);
            pme.setMerId(baofuPayConfig.getMemberid());
            pme.setTerId(baofuPayConfig.getTerminalid());
            pme.setMethod(method);
            log.info("请求参数："+pme);
            String PostString  = HttpUtil.RequestForm(baofuPayConfig.getPayUrl(),pme);
            log.info(PostString);
            ResultMasterEntity rme =  JSON.parseObject(PostString,ResultMasterEntity.class);
            log.info(rme.toString());
            if(rme.getReturnCode().equals("SUCCESS")){
                if(JHSignatureUtils.verifySignature(baofuPayConfig.getCerpath(), rme.getDataContent(), rme.getSignStr())){
                    log.info("验签：YES");
                    JSONObject json =JSON.parseObject(rme.getDataContent());
                    if(json.getString("resultCode").equals("SUCCESS")){
                        if(json.getString("refundState").equals("REFUND_ERROR") || json.getString("refundState").equals("ABNORMAL")){
                            throw new ServiceException("退款失败："+json.getString("errMsg"));
                        }
                        JSONObject json1 =JSON.parseObject(json.getString("chlRetParam"));
                        Map<String,Object> map = JSON.parseObject(rme.getDataContent(),Map.class);
                        return map;
                    }else {
                        throw new ServiceException(json.getString("errMsg"));
                    }
                }else{
                    log.info("验签：NO");
                    throw new ServiceException("退款验签失败");
                }
            }else {
                throw new ServiceException(rme.getReturnMsg());
            }

            //String originTradeNo="";//原支付订单宝付订单号
            // String merchantName="";//商户名称
            //String originOutTradeNo="OTN1731591653279";//原支付订单商户订单号 [与原支付订单宝付交易号二选一比传]
        }catch (Exception e){
            throw new ServiceException(e.getMessage());
        }

    }

    public static String getIpAddress() {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        System.out.println(ip);
        return ip;
    }

    public static    Map<String,Object> toUnderlineCase(Map<String,Object> map){
        Map<String, Object> camelCaseMap = new HashMap<>();
        for (String key : map.keySet()) {
            String camelCaseKey = StrUtil.toUnderlineCase(key);
            System.out.println(camelCaseKey);
            camelCaseMap.put(camelCaseKey, map.get(key));
        }
        camelCaseMap.put("package_value",camelCaseMap.get("package"));
        return camelCaseMap;
    }


    public static void main(String[] args) {
        // 创建一个包含下划线格式键的 Map
        Map<String, Object> underscoreMap = new HashMap<>();
        underscoreMap.put("firstName", "John");
        underscoreMap.put("lastName", "Doe");
        underscoreMap.put("emailAddress", "john.doe@example.com");
        Map<String, Object> camelCaseMap = toUnderlineCase(underscoreMap);
        for (String key : camelCaseMap.keySet()) {
            System.out.println(key + ":" + camelCaseMap.get(key));
        }
    }
}
